//
// Copyright (c) 2009 All Right Reserved
//
// vl
//
// 2009-01-01
// Contains ...
using System;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;
using System.Xml.Serialization;
namespace LargoCommon.Music
{
/// Formal harmonic state.
/// Harmonic state represents relations in one formal harmonic structure
/// and enable to Compute its characteristics (continuity, impulse,..).
[Serializable]
[XmlRoot]
public sealed class HarmonicStateFormal : HarmonicTransfer {
#region Fields
/// Binary schema.
[NonSerialized]
private readonly BinarySchema binSchema;
#endregion
#region Constructors
/// Initializes a new instance of the HarmonicStateFormal class. Serializable.
public HarmonicStateFormal() {
}
/// Initializes a new instance of the HarmonicStateFormal class.
/// Harmonic system.
/// Harmonic structure.
public HarmonicStateFormal(HarmonicSystem harmonicSystem, BinarySchema binarySchema)
: base(harmonicSystem) {
Contract.Requires(harmonicSystem != null);
Contract.Requires(binarySchema != null);
this.binSchema = binarySchema;
this.AddAllIntervals();
this.SetFormalProperties();
}
/// Initializes a new instance of the HarmonicStateFormal class.
/// Harmonic system.
/// Binary schema.
/// Element of system.
public HarmonicStateFormal(
HarmonicSystem harmonicSystem, BinarySchema binarySchema, byte element)
: base(harmonicSystem) {
Contract.Requires(harmonicSystem != null);
Contract.Requires(binarySchema != null);
this.binSchema = binarySchema;
this.AddIntervalsLeadingToElement(element);
this.SetFormalProperties();
}
///
/// Initializes a new instance of the HarmonicStateFormal class.
///
/// The given system.
public HarmonicStateFormal(HarmonicSystem givenSystem)
: base(givenSystem) {
Contract.Requires(givenSystem != null);
}
#endregion
#region Public Properties
/// Gets binary schema.
/// Property description.
[XmlIgnore]
public BinarySchema BinarySchema {
get {
Contract.Ensures(Contract.Result() != null);
if (this.binSchema == null) {
throw new InvalidOperationException("Schema is null.");
}
return this.binSchema;
}
}
#endregion
#region Public static methods
/// Returns root values of elements in the structure.
/// Harmonic structure.
/// Returns value.
[JetBrains.Annotations.PureAttribute]
public static Collection RootValues(HarmonicStructure harmonicStructure) {
Contract.Requires(harmonicStructure != null);
//// if (harmonicStructure == null) { return null; }
var hS = harmonicStructure.HarmonicSystem;
var order = hS.Order;
var values = new Collection();
for (byte e = 0; e < order; e++) {
var state = new HarmonicStateFormal(hS, harmonicStructure, e);
var formalContinuity = state.MeanValueOfProperty(GenProperty.InnerContinuity, false, false);
values.Add(formalContinuity);
}
return values;
}
/// Returns principal values of elements in the structure.
/// Harmonic structure.
/// Returns value.
[JetBrains.Annotations.PureAttribute]
public static Collection PrincipalValues(HarmonicStructure harmonicStructure) {
Contract.Requires(harmonicStructure != null);
//// if (harmonicStructure == null) { return null; }
var hS = harmonicStructure.HarmonicSystem;
var order = hS.Order;
var values = new Collection();
for (byte e = 0; e < order; e++) {
var state = new HarmonicStateFormal(hS, harmonicStructure, e);
var formalContinuity = state.MeanValueOfProperty(GenProperty.InnerContinuity, true, false);
values.Add(formalContinuity);
}
return values;
}
#endregion
#region Public methods
/// Fills the given array with formal intervals to given element.
/// Element of system.
public void AddIntervalsLeadingToElement(byte elementTo) {
var places = this.BinarySchema.Places;
//// MusicalInterval interval = new MusicalInterval(this.HarmonicSystem, elementFrom, elementTo);
//// Math.Abs?!? (otherwise 2 times more intervals), GetFormalInterval(formalLength))
//// Do not convert to linq!!!
foreach (byte elementFrom in places) {
var systemLength = elementTo - elementFrom;
if (systemLength > 0) { //// Math.Abs?!? (otherwise 2 times more intervals)
var formalLength = GeneralSystem.FormalLength(this.HarmonicSystem.Order, systemLength);
var interval = this.HarmonicSystem.Intervals[formalLength];
this.Intervals.Add(interval);
}
}
}
#endregion
#region Private methods
/// Makes array of intervals between tones of the cluster.
private void AddAllIntervals() {
var places = this.BinarySchema.Places;
foreach (var elem in places) {
this.AddIntervalsLeadingToElement(elem);
}
}
#endregion
}
}